﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Xml;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using VideoPlay.Services.Models;
using VideoPlay.Services.Helpers;

namespace VideoPlay.Services
{
    public class PhoneService : IPhoneService
    {
        const string LIST_CATEGORY_URL = "http://blebleble.byethost22.com/mtes/services.php?function=getcategory";
        const string LIST_VIDEO_URL = "http://blebleble.byethost22.com/mtes/services.php?function=getlist&categoryid={0}&paging={1}&rownumber={2}";
        const string YOUTUBE_SEARCH_URL = "https://www.googleapis.com/youtube/v3/search?part=snippet&key=AIzaSyCU4Q2ob9kN3Ld2DxCkVw2Pk5ERxfC03io&maxResults={0}&type=video&q={1}";
        const string YOUTUBE_SEARCHV2_URL = "http://gdata.youtube.com/feeds/api/videos?q={0}&start-index={1}&max-results={2}&v=2";
        const string YOUTUBE_VIDEO_URL = "https://www.googleapis.com/youtube/v3/videos?id={0}&part=contentDetails&key=AIzaSyCU4Q2ob9kN3Ld2DxCkVw2Pk5ERxfC03io";
        const string YOUTUBE_PLAY_VIDEO_URL = "https://www.youtube.com/watch?v={0}";

        const string YOUTUBE_API_KEY = "AIzaSyCU4Q2ob9kN3Ld2DxCkVw2Pk5ERxfC03io";

        private const string BotUserAgent = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)";


        Action<object> onCompleted;

        public void RetrieveCategoriesAsync(Action<object> onCompleted)
        {
            this.onCompleted = onCompleted;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += DowloadCategoriesCompleted;
            client.DownloadStringAsync(new Uri(LIST_CATEGORY_URL));
        }

        void DowloadCategoriesCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
            {

            }
            else
            {
                List<Categories> categories = JsonConvert.DeserializeObject<List<Categories>>(e.Result);
                this.onCompleted(categories);
            }
        }

        public void RetrieveVideosAsync(int categoryId, int page, int numberOfRows, Action<object> onCompleted)
        {
            this.onCompleted = onCompleted;

            WebClient client = new WebClient();
            client.DownloadStringCompleted += DownloadVideosCompleted;
            client.DownloadStringAsync(new Uri(string.Format(LIST_VIDEO_URL, categoryId, page, numberOfRows)));
        }

        void DownloadVideosCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
            {

            }
            else
            {
                List<Videos> videos = JsonConvert.DeserializeObject<List<Videos>>(e.Result);
                this.onCompleted(videos);
            }
        }

        public void SearchVideosV2(string term, int page, int numberOfRows, Action<object> onCompleted)
        {
            page = page < 1 ? 1 : page;
            this.onCompleted = onCompleted;

            WebClient client = new WebClient();
            client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)";
            client.DownloadStringCompleted += SearchVideosV2Completed;
            client.DownloadStringAsync(new Uri(string.Format(YOUTUBE_SEARCHV2_URL,Uri.EscapeUriString(term), page * numberOfRows,numberOfRows)), numberOfRows);
        }

        void SearchVideosV2Completed(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                onCompleted(null);
            }
            else
            {
                List<List> videos = YoutubeData.ParseSearchResultV2(e.Result);
                onCompleted(videos);
            }
        }

        public void SearchVideos(string term, int page, int numberOfRows, Action<object> onCompleted)
        {
            page = page < 1 ? 1 : page;
            this.onCompleted = onCompleted;

            WebClient client = new WebClient();
            client.Headers["User-Agent"] = BotUserAgent;
            client.UseDefaultCredentials = true;
            client.DownloadStringCompleted += SearchVideosCompleted;
            client.DownloadStringAsync(new Uri(string.Format(YOUTUBE_SEARCH_URL, page * numberOfRows, Uri.EscapeUriString(term))), numberOfRows);
        }

        void SearchVideosCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                onCompleted(null);
            }
            else
            {
                YoutubeSearchResult videos = JsonConvert.DeserializeObject<YoutubeSearchResult>(e.Result);

                if ((int)e.UserState != 0)
                {
                    int page = videos.items.Count / (int)e.UserState;
                    int numberOfRows = (int)e.UserState;

                    videos.items = videos.items.Skip((page - 1) * numberOfRows).Take(numberOfRows).ToList();
                }

                FillDurations(videos);
            }
        }

        private void FillDurations(YoutubeSearchResult videos)
        {
            string idsToSearch = BuildIdString(videos);

            WebClient client = new WebClient();
            client.DownloadStringCompleted += ListVideosCompleted;
            client.DownloadStringAsync(new Uri(string.Format(YOUTUBE_VIDEO_URL, idsToSearch)), videos);
        }

        void ListVideosCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                onCompleted(null);
            }
            else
            {
                List<List> resultList = new List<List>();

                YoutubeSearchResult videos = e.UserState as YoutubeSearchResult;

                JObject result = JObject.Parse(e.Result);
                JArray itemArray = (JArray)result["items"];
                foreach (var item in itemArray.Children())
                {
                    YoutubeVideoResult itemResult = JsonConvert.DeserializeObject<YoutubeVideoResult>(item.ToString());
                    Item videoToUpdate = (from video in videos.items
                                          where video.id.videoId.Equals(itemResult.id)
                                          select video).FirstOrDefault();
                    List localVideo = new List();
                    localVideo.youtubeId = itemResult.id;
                    localVideo.title = videoToUpdate.snippet.title;
                    localVideo.image = videoToUpdate.snippet.thumbnails.@default.url;
                    localVideo.url = string.Format(YOUTUBE_PLAY_VIDEO_URL, localVideo.youtubeId);
                    localVideo.duration = ParseISO8601String(itemResult.contentDetails.duration);

                    resultList.Add(localVideo);
                }

                onCompleted(resultList);
            }
        }

        private TimeSpan ParseISO8601String(string duration)
        {
            TimeSpan result = XmlConvert.ToTimeSpan(duration);
            return result;
        }

        private string BuildIdString(YoutubeSearchResult videos)
        {
            if (videos.items.Count < 1)
                return string.Empty;

            string result = string.Empty;

            foreach (var video in videos.items)
            {
                result += video.id.videoId + ",";
            }
            result = result.Substring(0, result.Length - 1);

            return result;
        }


        public void ShareVideo(string videoUrl, string message)
        {
            throw new NotImplementedException();
        }

        public void LikeUnLike(List video)
        {
            throw new NotImplementedException();
        }
    }
}
